﻿// 开发者:micropu
// 公司:佛山远钧智慧科技有限公司

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Http;
using TouchSocket.Http.WebSockets;


namespace Admin.NET.Application;

/// <summary>
/// 插件接收消息
/// </summary>
public class ClientReceivePlugin : PluginBase, IWebSocketHandshakedPlugin
{
    private readonly ILog m_logger;

    public ClientReceivePlugin(ILog logger)
    {
        this.m_logger = logger;
    }

    /// <summary>
    /// 拦截握手成功的消息
    /// </summary>
    /// <param name="client"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    public async Task OnWebSocketHandshaked(IWebSocket client, HttpContextEventArgs e)
    {
        // 当WebSocket想要使用ReadAsync时，需要设置此值为true
        client.AllowAsyncRead = true;
        string deviceSn = string.Empty;
        var clientWebSocketManager = App.GetService<IClientWebSocketManager>();

        //此处即表明websocket已连接
        while (true)
        {
            using (var receiveResult = await client.ReadAsync(CancellationToken.None))
            {
                //Console.WriteLine(JsonConvert.SerializeObject(receiveResult));

                if (receiveResult.DataFrame == null)
                {
                    break;
                }

                //判断是否为最后数据
                //例如发送方发送了一个10Mb的数据，接收时可能会多次接收，所以需要此属性判断。
                if (receiveResult.DataFrame.FIN)
                {
                    if (receiveResult.DataFrame.IsText)
                    {
                        // Console.WriteLine(JsonConvert.SerializeObject(receiveResult.DataFrame.ToText()));
                        // this.m_logger.Info($"接收WebSocket文本：{receiveResult.DataFrame.ToText()}");

                        //var json = JsonConvert.DeserializeObject<ConcurrentDictionary<string, string>>(receiveResult.DataFrame.ToText());
                        //// 收到心跳包时连接
                        //if (json != null && json.ContainsKey("device_sn") && json["cmd"] == "heart beat")
                        //{
                        //    this.m_logger.Info($"WebSocket文本：{receiveResult.DataFrame.ToText()}");
                        //    deviceSn = json["device_sn"];
                        //    clientWebSocketManager.AddConnection(deviceSn, client);
                        //}
                        //else
                        //{
                        //    this.m_logger.Info($"WebSocket文本：{receiveResult.DataFrame.ToText()}");
                        //    clientWebSocketManager.ReceiveMessage(deviceSn, receiveResult.DataFrame.ToText());
                        //    Console.WriteLine(receiveResult.DataFrame.ToText());
                        //}


                        //你可以通过定义一个匿名类型来反序列化 JSON 字符串。这样可以在编译时保证类型安全。
                        var template = new
                        {
                            addr_name = string.Empty,
                            addr_no = string.Empty,
                            cmd = string.Empty,
                            device_no = string.Empty,
                            device_sn = string.Empty,
                            ip = string.Empty,
                            version = string.Empty
                        };

                        var json = JsonConvert.DeserializeAnonymousType(receiveResult.DataFrame.ToText(), template);
                        if (json != null && !string.IsNullOrWhiteSpace(json.device_sn))
                        {
                            // 收到心跳包时连接
                            if (json.cmd == "heart beat")
                            {
                                deviceSn = json.device_sn;
                                clientWebSocketManager.AddConnection(deviceSn, client);
                            }
                            else
                            {
                                deviceSn = json.device_sn;
                                clientWebSocketManager.ReceiveMessage(deviceSn, receiveResult.DataFrame.ToText());
                            }
                        }
                    }
                }
            }
        }

        //此处即表明websocket已断开连接
        this.m_logger.Info("WebSocket断开连接");
        if (!string.IsNullOrWhiteSpace(deviceSn)) await clientWebSocketManager.RemoveConnectionAsync(deviceSn);
        await e.InvokeNext();
    }
}
